package com.service.business.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.util.ObjectUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;

/**
 * <dl>
 * <dt>platform</dt>
 * <dd>Description:</dd>
 * <dd>Copyright: Copyright (C) 2018</dd>
 * <dd>Company: </dd>
 * <dd>CreateDate: 2019-04-14</dd>
 * </dl>
 */
@Slf4j
public class DateUtil {

	public static String pattern_ymd = "yyyy-MM-dd";

	public static long getNowSec() {
		return System.currentTimeMillis() / 1000;
	}

	public static long getSec(Date date) {
		return date.getTime() / 1000;
	}

	public static Date getOnlyDay(Date date) {
		Date date1 = null;
		try {
			date1 = org.apache.commons.lang3.time.DateUtils.parseDate(DateFormatUtils.format(date, "yyyy-MM-dd"), "yyyy-MM-dd");
		} catch (ParseException e) {
			e.printStackTrace();
			log.error("日期格式化异常");
		}
		return date1;
	}

	public static String getOnlyDay2String(Date date) {
		return getOnlyDay2String(date, pattern_ymd);
	}

	public static String getOnlyDay2String(Date date, String pattern) {
		return DateFormatUtils.format(date, pattern);
	}

	public static Date addDay(Date date, int add) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, add);
		return calendar.getTime();
	}

	public static Long getStartOfDate(Date date) {
		Calendar dateCalendar = Calendar.getInstance();
		dateCalendar.setTime(date);
		dateCalendar.set(Calendar.HOUR_OF_DAY, 0);
		return setDateZero(dateCalendar);
	}

	public static Date getDayOfStart(Date date) {
		Calendar dateCalendar = Calendar.getInstance();
		dateCalendar.setTime(date);
		dateCalendar.set(Calendar.HOUR_OF_DAY, 0);
		return setDateZero2Date(dateCalendar);
	}

	/**
	 * LocalDate转Date
	 *
	 * @param localDate
	 * @return
	 */
	public static Date getDayOfStart(LocalDate localDate) {
		if (null == localDate) {
			return null;
		}
		ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
		return Date.from(zonedDateTime.toInstant());
	}

	public static Date getDayOfEnd(Date date) {
		Calendar dateCalendar = Calendar.getInstance();
		dateCalendar.setTime(date);
		dateCalendar.set(Calendar.HOUR_OF_DAY, 24);
		return setDateZero2Date(dateCalendar);
	}

	public static Long getEndOfDate(Date date) {
		Calendar dateCalendar = Calendar.getInstance();
		dateCalendar.setTime(date);
		dateCalendar.set(Calendar.HOUR_OF_DAY, 24);
		return setDateZero(dateCalendar);
	}


	private static Long setDateZero(Calendar dateCalendar) {
		dateCalendar.set(Calendar.MINUTE, 0);
		dateCalendar.set(Calendar.SECOND, 0);
		dateCalendar.set(Calendar.MILLISECOND, 0);
		return getSec(dateCalendar.getTime());
	}

	private static Date setDateZero2Date(Calendar dateCalendar) {
		dateCalendar.set(Calendar.MINUTE, 0);
		dateCalendar.set(Calendar.SECOND, 0);
		dateCalendar.set(Calendar.MILLISECOND, 0);
		return dateCalendar.getTime();
	}

	public static Long getValidTime(Date createTime, Integer overdueTime) {
		Date overdueDate = DateUtils.addMinutes(createTime, overdueTime);
		long lastTime = overdueDate.getTime() - new Date().getTime();
		return lastTime > 0 ? lastTime : 0;
	}

	public static boolean isWeekend(Date someday) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(someday);
		return cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY;
	}

	public static long getOpenTime(Date date, Integer type) {
		int timeType = 60 * type;
		return (long) (Math.floor(date.getTime() / (1000.0 * timeType)) * (timeType));
	}

	public static long getDayOfStart2Sec(Date date) {
		return getDayOfStart(date).getTime() / 1000;
	}

	public static long getBeginDayOfWeek(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
		if (dayOfWeek == 1) {
			dayOfWeek += 7;
		}
		cal.add(Calendar.DATE, 2 - dayOfWeek);
		return getDayOfStart2Sec(cal.getTime());
	}

	/**
	 * 获取当前时间的下一个月时间
	 *
	 * @return
	 */
	public static Date nextMonth() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.MONTH, 1);
		return cal.getTime();
	}

	/**
	 * 将时间挪到下午15:00
	 *
	 * @param date
	 * @return
	 */
	public static Date changeDateTo3point(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		// 将时分秒,毫秒域清零
		calendar.set(Calendar.HOUR_OF_DAY, 14);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 00);
		return calendar.getTime();
	}

	public static Date nDaysAfterDate(Integer daysNum) {
		if (ObjectUtils.isEmpty(daysNum) || daysNum == 0) {
			daysNum = 1;
		}
		Calendar calendar2 = Calendar.getInstance();
		SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
		calendar2.add(Calendar.DATE, daysNum);
		String three_days_after = sdf1.format(calendar2.getTime());
		String nDaysAfterStr = three_days_after + " 00:00:00";
		System.out.println(nDaysAfterStr);
		SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date returnDate = null;
		try {
			returnDate = sdf2.parse(nDaysAfterStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return returnDate;
	}


	public static Date nextCurrentDays(Date date, int nextNum) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date); //需要将date数据转移到Calender对象中操作
		calendar.add(calendar.DATE, nextNum);//把日期往后增加n天.正数往后推,负数往前移动
		date = calendar.getTime();   //这个时间就是日期往后推一天的结果
		return date;
	}

	/**
	 * date2比date1多的天数
	 *
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int differentDays(Date date1, Date date2) {
		Calendar cal1 = Calendar.getInstance();
		cal1.setTime(date1);
		Calendar cal2 = Calendar.getInstance();
		cal2.setTime(date2);
		int day1 = cal1.get(Calendar.DAY_OF_YEAR);
		int day2 = cal2.get(Calendar.DAY_OF_YEAR);
		int year1 = cal1.get(Calendar.YEAR);
		int year2 = cal2.get(Calendar.YEAR);
		if (year1 != year2) //同一年
		{
			int timeDistance = 0;
			for (int i = year1; i < year2; i++) {
				if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) //闰年
				{
					timeDistance += 366;
				} else //不是闰年
				{
					timeDistance += 365;
				}
			}
			return timeDistance + (day2 - day1);
		} else //不同年
		{
			return day2 - day1;
		}
	}
}
